Skip to content

Conversation

@jkczyz
Copy link
Contributor

@jkczyz jkczyz commented Mar 10, 2025

Splicing allows either node to send tx_init_rbf as they may want to take the opportunity to contribute or withdraw additional funds to / from the channel. Allow the same for v2 channel establishment for consistency.

Copy link
Collaborator

@t-bast t-bast left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have prototyped this in ACINQ/eclair#3021 and I don't see any reason to disallow it.

Copy link
Collaborator

@t-bast t-bast left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Copy link
Contributor

@vincenzopalazzo vincenzopalazzo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Splicing allows either node to send `tx_init_rbf` as they may want to
take the opportunity to contribute or withdraw additional funds to /
from the channel. Allow the same for v2 channel establishment for
consistency.
@jkczyz jkczyz force-pushed the 2025-03-dual-funding-rbf branch from 7feaee0 to 966e550 Compare July 14, 2025 20:22
@jkczyz
Copy link
Contributor Author

jkczyz commented Jul 14, 2025

Squashed the fixups. @vincenzopalazzo Anyone else from CLN need to chime in on this?

Copy link
Collaborator

@t-bast t-bast left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 966e550

@ddustin
Copy link
Contributor

ddustin commented Aug 25, 2025

I haven't tested it but this should work fine in CLN. We essentially treat RBF as just a splice_init anyway.

@t-bast
Copy link
Collaborator

t-bast commented Aug 26, 2025

@ddustin be careful, it must NOT be treated as splice_init, this is very different. If you treat it as splice_init, you're going to create a child transaction that spends the pending funding transaction. On the contrary, we want to create an RBF attempt, that double-spends (replaces) the pending funding transaction.

@t-bast
Copy link
Collaborator

t-bast commented Sep 9, 2025

@ddustin I tested against lightningd v25.09 and got this error: "Only the channel initiator is allowed to initiate RBF". So it looks like this isn't implemented in lightningd yet?

The sender of `tx_init_rbf`:
- MUST be the *initiator*
- MAY be either the *initiator* or the *accepter*
- If the sender is the accepter, it becomes the initiator of the `interactive-tx` session and thus:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello! Looking at updating CLN to accommodate this, and ran into a question which seems obvious but wanted to confirm.

I'm taking this to mean that the serial_ids and all other role-related indicators are swapped for the entirety of the tx construction phase?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct

niftynei added a commit to niftynei/lightning that referenced this pull request Oct 21, 2025
Work in progress to allow acceptor to initiate an RBF

Mostly works, except that the original funder isn't setup to re-add
their original funds to the channel, so the init fails because it's
missing any overlapping inputs.

lightning/bolts#1236
@niftynei
Copy link
Collaborator

Is it an implementation detail to have the OG opening peer re-adding their original inputs to the transaction or is that something we should specify?

@jkczyz
Copy link
Contributor Author

jkczyz commented Oct 21, 2025

Is it an implementation detail to have the OG opening peer re-adding their original inputs to the transaction or is that something we should specify?

I'd say it's an implementation detail. They could choose to not add them / take the opportunity to use entirely different inputs / amounts.

@jkczyz
Copy link
Contributor Author

jkczyz commented Oct 21, 2025

I'd say it's an implementation detail. They could choose to not add them / take the opportunity to use entirely different inputs / amounts.

Oh, and since they are no longer the initiator, they wouldn't be paying for the common fields nor the funding output. So they may decide to choose different UTXOs to spend as their fee responsibility may decrease.

@niftynei
Copy link
Collaborator

niftynei commented Oct 21, 2025 via email

@t-bast
Copy link
Collaborator

t-bast commented Oct 22, 2025

One issue we ran into on CLN is that without a common input with the
previous tx, the RBF attempt fails (our checks don’t allow a second tx for
a channel to be signed).

Agreed, we want to ensure that there is a common input with the previous versions of the transaction, otherwise they don't double-spend each other and we can in theory end up with two confirmed funding transactions for the same channel! But as long as the initiator of the RBF ensures that they double-spend themselves, it's fine?

Note that if you didn't have any input in the previous interactive-txs, then you have no reason to initiate RBF, you don't have any balance in that channel. If you do initiate RBF anyway, you then indeed need to check that your peer re-adds an input so that this new interactive-tx double-spends all previous attempts.

@niftynei
Copy link
Collaborator

niftynei commented Oct 22, 2025

Had a quick chat with @rustyrussell about this and he suggested we add a simple rule: For any RBF attempt (independent of who's initiated it) the node must include at least one of their inputs from the previous transaction.

This would allow for anyone to initiate an RBF (independent of what they've previously contributed) and also guarantee that there's never an issue with forgetting to include overlapping inputs with the prior version of the transaction.

niftynei added a commit to niftynei/lightning that referenced this pull request Oct 23, 2025
Work in progress to allow acceptor to initiate an RBF

Mostly works, except that the original funder isn't setup to re-add
their original funds to the channel, so the init fails because it's
missing any overlapping inputs.

lightning/bolts#1236
@t-bast
Copy link
Collaborator

t-bast commented Oct 24, 2025

Had a quick chat with @rustyrussell about this and he suggested we add a simple rule: For any RBF attempt (independent of who's initiated it) the node must include at least one of their inputs from the previous transaction.

I thought this was already in the spec, but I cannot find it. This is already a requirement today, even when the initiator is the only one allowed to RBF, so this should have been specified in the dual funding PR.

@jkczyz can you add that requirement in the tx_init_rbf section (https://github.com/lightning/bolts/blob/master/02-peer-protocol.md#the-tx_init_rbf-message)? It could be something like:

The sender:

- MUST send `tx_add_input` with at least one input that it used in previous transaction construction attempts (if it contributed to previous transactions), to ensure that the new transaction double-spends all other attempts.

We should also add a requirement in the tx_complete section (https://github.com/lightning/bolts/blob/master/02-peer-protocol.md#the-tx_complete-message):

The receiving node:

- MUST fail the negotiation if: 
  - `tx_init_rbf` was used and the transaction does not double-spend all previous attempts.

Does that match what is already implemented in ldk and cln? This is what eclair does and enforces already.

@jkczyz
Copy link
Contributor Author

jkczyz commented Oct 24, 2025

I thought this was already in the spec, but I cannot find it. This is already a requirement today, even when the initiator is the only one allowed to RBF, so this should have been specified in the dual funding PR.

@jkczyz can you add that requirement in the tx_init_rbf section (https://github.com/lightning/bolts/blob/master/02-peer-protocol.md#the-tx_init_rbf-message)? It could be something like:

The sender:

- MUST send `tx_add_input` with at least one input that it used in previous transaction construction attempts (if it contributed to previous transactions), to ensure that the new transaction double-spends all other attempts.

Should we include the requirement for the sender of tx_ack_rbf, too?

For v2 establishment, if the RBF initiator did not contribute to previous attempts, couldn't the other party refuse to add one of their previous inputs? I guess they wouldn't have an incentive to -- if they're the original initiator then they wanted to open the channel -- but an implementation may (inadvertently) choose a different UTXO because fee responsibilities would have changed now that they need to pay for less. Similarly for any subsequent RBF attempts.

It may be too strict a requirement, though, when both parties have contributed to a previous attempt. Just trying to think if there's a way to state the requirement to avoid a scenario where we can't RBF again because one party isn't aware they need to contribute a specific input.

Also, presumably, you will update the splicing PR to elide the new tx_init_rbf requirement?

We should also add a requirement in the tx_complete section (https://github.com/lightning/bolts/blob/master/02-peer-protocol.md#the-tx_complete-message):

The receiving node:

- MUST fail the negotiation if: 
  - `tx_init_rbf` was used and the transaction does not double-spend all previous attempts.

Hmmm.. There are two sections named "The tx_complete Message". The one under "Channel Establishment v2" has requirements for after exchanging consecutive messages and already covers this.

Does that match what is already implemented in ldk and cln? This is what eclair does and enforces already.

LDK hasn't implemented RBF yet.

@t-bast
Copy link
Collaborator

t-bast commented Oct 27, 2025

Should we include the requirement for the sender of tx_ack_rbf, too?

Yes, good point!

For v2 establishment, if the RBF initiator did not contribute to previous attempts, couldn't the other party refuse to add one of their previous inputs? I guess they wouldn't have an incentive to -- if they're the original initiator then they wanted to open the channel -- but an implementation may (inadvertently) choose a different UTXO because fee responsibilities would have changed now that they need to pay for less. Similarly for any subsequent RBF attempts.

Note that the RBF initiator actually has to contribute funds, because they must pay for the fees of the common transaction fields and the channel output, which is impossible to do if they don't add any input to the transaction.

There are indeed weird games that nodes can play if they don't have an incentive to accept the RBF attempt (but in most cases they do, the other side will be the one paying more fees since the RBF initiator pays fees for the common transaction fields). Anyway, I don't think it matters that much: any games that nodes play during RBF will be caught by the tx_complete requirement, where once each side has added all of their inputs/outputs, both nodes must verify that this new transaction double-spends all previous attempts, and fail otherwise.

an implementation may (inadvertently) choose a different UTXO because fee responsibilities would have changed now that they need to pay for less. Similarly for any subsequent RBF attempts.

I think that the implementation should prevent that: if you're paying less fees, you should re-use the same UTXO(s) but increase your change output (or add one if there wasn't any before).

Also, presumably, you will update the splicing PR to elide the new tx_init_rbf requirement?

Good point as well, we can remove this requirement entirely for the splicing case since the previous channel output ensures the double-spending condition.

Hmmm.. There are two sections named "The tx_complete Message". The one under "Channel Establishment v2" has requirements for after exchanging consecutive messages and already covers this.

Right, I missed it because it's not in the table of contents, but it does state what we want! I was surprised it wasn't already present, it's a good thing that it actually is here (and it makes sense to have in the "Channel Establishment v2" section, since splicing won't need this check).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants